<template>
	<view>
		<view v-if="sharedConversationState.currentConversationInfo == null" class="conversation-empty-container">
			<text>^~^</text>
		</view>
		<view
			v-else
			ref="conversationContentContainer"
			class="conversation-content-container"
			:dummy_just_for_reactive="currentVoiceMessage"
		>
			<view class="message-list-container">
				<scroll-view
					ref="conversationMessageList"
					class="message-list"
					scroll-y="true"
					:scroll-top="scrollTop"
					:scroll-into-view="'id-' + lastMessageId"
					refresher-enabled="true"
					:refresher-triggered="triggered"
					:refresher-threshold="45"
					refresher-background="lightgreen"
					@refresherpulling="onPulling"
					@refresherrefresh="onRefresh"
					@refresherrestore="onRestore"
					@refresherabort="onAbort"
					@scroll="onScroll"
				>
					<view
						v-for="message in sharedConversationState.currentConversationMessageList"
						:id="'id-' + message.messageId"
						:key="message.messageId"
					>
						<!--todo 不同的消息类型 notification in out-->

						<NotificationMessageContentView :message="message" v-if="isNotificationMessage(message)" />
						<RecallNotificationMessageContentView :message="message" v-else-if="isRecallNotificationMessage(message)" />
						<NormalOutMessageContentView
							@click.native.capture.stop="
								sharedConversationState.enableMessageMultiSelection ? clickMessageItem($event, message) : null
							"
							:message="message"
							@touchstart.native="onTouchStart"
							@touchmove.native="onTouchMove"
							v-else-if="message.direction === 0 && sharedConversationState.enableMessageMultiSelection"
						/>
						<NormalOutMessageContentView
							:message="message"
							@touchstart.native="onTouchStart"
							@touchmove.native="onTouchMove"
							v-else-if="message.direction === 0 && !sharedConversationState.enableMessageMultiSelection"
						/>
						<NormalInMessageContentView
							@click.native.capture.stop="
								sharedConversationState.enableMessageMultiSelection ? clickMessageItem($event, message) : null
							"
							:message="message"
							@touchstart.native="onTouchStart"
							@touchmove.native="onTouchMove"
							v-else-if="message.direction === 1 && sharedConversationState.enableMessageMultiSelection"
						/>
						<NormalInMessageContentView
							:message="message"
							@touchstart.native="onTouchStart"
							@touchmove.native="onTouchMove"
							v-else
						/>
					</view>
				</scroll-view>
			</view>
			<!--            <view v-show="!sharedConversationState.enableMessageMultiSelection"-->
			<!--                  class="viewider-handler"></view>-->
			<chunLei-popups
				v-model="showContextMenu"
				:popData="contextMenuItems"
				@tapPopup="onContextMenuItemSelect"
				:x="contextMenuX"
				:y="contextMenuY"
				direction="column"
				theme="dark"
				:triangle="false"
				dynamic
			/>
			<MessageInputView
				:conversationInfo="sharedConversationState.currentConversationInfo"
				v-show="!sharedConversationState.enableMessageMultiSelection"
				class="message-input-container"
				ref="messageInputView"
			/>
			<MultiSelectActionView v-show="sharedConversationState.enableMessageMultiSelection" />
		</view>
	</view>
</template>

<script>
	import MessageInputView from '@/pages/conversation/MessageInputView'
	import NormalOutMessageContentView from '@/pages/conversation/message/NormalOutMessageContentContainerView'
	import NormalInMessageContentView from '@/pages/conversation/message/NormalInMessageContentContainerView'
	import NotificationMessageContentView from '@/pages/conversation/message/NotificationMessageContentView'
	import RecallNotificationMessageContentView from '@/pages/conversation/message/RecallNotificationMessageContentView'
	import NotificationMessageContent from '@/wfc/messages/notification/notificationMessageContent'
	import TextMessageContent from '@/wfc/messages/textMessageContent'
	import store from '@/store'
	import wfc from '../../wfc/client/wfc'
	import { numberValue, stringValue } from '@/wfc/util/longUtil'
	import MultiSelectActionView from '@/pages/conversation/MessageMultiSelectActionView'
	import ForwardType from '@/pages/conversation/message/forward/ForwardType'
	import FileMessageContent from '@/wfc/messages/fileMessageContent'
	import ImageMessageContent from '@/wfc/messages/imageMessageContent'
	// import {copyImg, copyText} from "@/pages/util/clipboard";
	import Message from '@/wfc/messages/message'
	import VideoMessageContent from '@/wfc/messages/videoMessageContent'
	import SoundMessageContent from '@/wfc/messages/soundMessageContent'
	import MessageContentType from '@/wfc/messages/messageContentType'
	// import BenzAMRRecorder from "benz-amr-recorder";
	// import axios from "axios";
	import FavItem from '@/wfc/model/favItem'
	import ConversationType from '@/wfc/model/conversationType'
	import GroupMemberType from '@/wfc/model/groupMemberType'
	import CompositeMessageContent from '@/wfc/messages/compositeMessageContent'
	import ConnectionStatus from '../../wfc/client/connectionStatus'
	import { getItem, setItem } from '../util/storageHelper'

	var amr
	export default {
		name: 'ConversationPage',
		components: {
			MultiSelectActionView,
			NotificationMessageContentView,
			RecallNotificationMessageContentView,
			NormalInMessageContentView,
			NormalOutMessageContentView,
			MessageInputView
		},
		// props: ["conversation"],
		data() {
			return {
				conversationInfo: store.state.conversation.currentConversationInfo,
				sharedConversationState: store.state.conversation,
				sharedContactState: store.state.contact,
				sharedPickState: store.state.pick,
				sharedMiscState: store.state.misc,

				savedMessageListViewHeight: -1,
				saveMessageListViewFlexGrow: -1,

				dragAndDropEnterCount: 0,

				showContextMenu: false,
				isScroll: false,
				touchStartX: 0,
				touchStartY: 0,
				contextMenuX: 0,
				contextMenuY: 0,
				contextMenuItems: [],
				lastScrollTop: 0,
				keyboardHeight: 0,
				currentKeyboardHeight: 0,
				scrollTop: 0,

				triggered: false
			}
		},

		onLoad() {
			// #ifdef APP-PLUS
			const currentWebview = this.$scope.$getAppWebview() //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
			// currentWebview.setBounce({position:{top:'100px'},changeoffset:{top:'0px'}}); //动态重设bounce效果
			currentWebview.overrideUrlLoading(
				{
					mode: 'reject'
					// match:'http.*'
				},
				(e) => {
					console.log('reject url', e.url)
					if (this.sharedConversationState.enableMessageMultiSelection) {
						return
					}
					uni.navigateTo({
						url: `/pages/misc/WebViewPage?url=${e.url}`,
						fail: (e) => {
							console.log('navigate to WebViewPage error', e)
						}
					})
				}
			)
			// #endif
		},

		onShow() {
			this.updateConversationTitle()
		},

		onNavigationBarButtonTap(e) {
			if (this.conversationInfo.conversation.type === ConversationType.Single) {
				uni.navigateTo({
					url: '/pages/conversation/SingleConversationInfoPage',
					success: (res) => {
						res.eventChannel.emit('conversationInfo', {
							conversationInfo: this.conversationInfo
						})
					},
					fail: (err) => {
						console.log('nav to SingleConversationInfoPage err', err)
					}
				})
			} else if (this.conversationInfo.conversation.type === ConversationType.Group) {
				uni.navigateTo({
					url: '/pages/conversation/GroupConversationInfoPage',
					success: (res) => {
						res.eventChannel.emit('conversationInfo', {
							conversationInfo: this.conversationInfo
						})
					},
					fail: (err) => {
						console.log('nav to GroupConversationInfoPage err', err)
					}
				})
			} else {
				uni.showToast({
					title: 'TODO 暂不支持该会话类型',
					icon: 'none'
				})
			}
		},

		onUnload() {
			store.setCurrentConversationInfo(null)
		},

		methods: {
			toggleMessageMultiSelectionActionView(message) {
				store.toggleMessageMultiSelection(message)
			},

			clickMessageItem(event, message) {
				if (message.messageContent instanceof NotificationMessageContent) {
					return
				}
				if (this.sharedConversationState.enableMessageMultiSelection) {
					store.selectOrDeselectMessage(message)
					event.stopPropagation()
					event.preventDefault()
				}
			},

			isNotificationMessage(message) {
				return (
					message &&
					message.messageContent instanceof NotificationMessageContent &&
					message.messageContent.type !== MessageContentType.RecallMessage_Notification
				)
			},

			isRecallNotificationMessage(message) {
				return message && message.messageContent.type === MessageContentType.RecallMessage_Notification
			},

			reedit(message) {
				this.$refs.messageInputView.insertText(message.messageContent.originalSearchableContent)
			},

			onScroll(e) {
				// hide tippy userCard
				// for (const popper of document.querySelectorAll('.tippy-popper')) {
				//     const instance = popper._tippy;
				//     if (instance.state.isVisible) {
				//         instance.hide();
				//     }
				// }
				// hide message context menu
				// this.$refs.menu && this.$refs.menu.close();
				// console.log('onScroollllll',e,  this.lastScrollTop, e.scrollTop, e.scrollTop < this.lastScrollTop)
				// if (!this.lastScrollTop){
				//     this.lastScrollTop = e.detail.deltaY;
				//     return;
				// }
				// if (e.detail.deltaY < this.lastScrollTop){
				//     this.$refs.messageInputView.minimizeMessageInputView();
				//     uni.hideKeyboard();
				// }
				// this.lastScrollTop =  e.detail.deltaY;
				// this.showContextMenu = false;
			},

			onMessageSenderContextMenuClose() {
				console.log('onMessageSenderContextMenuClose')
			},

			// message context menu
			isCopyable(message) {
				return (
					message &&
					(message.messageContent instanceof TextMessageContent ||
						message.messageContent instanceof ImageMessageContent)
				)
			},
			isDownloadAble(message) {
				return (
					message &&
					(message.messageContent instanceof ImageMessageContent ||
						message.messageContent instanceof FileMessageContent ||
						message.messageContent instanceof VideoMessageContent)
				)
			},

			isForwardable(message) {
				if (message && message.messageContent instanceof SoundMessageContent) {
					return false
				}
				return true
			},

			isFavable(message) {
				if (!message) {
					return false
				}
				return (
					[MessageContentType.VOIP_CONTENT_TYPE_START, MessageContentType.CONFERENCE_CONTENT_TYPE_INVITE].indexOf(
						message.messageContent.type
					) <= -1
				)
			},

			isRecallable(message) {
				if (message) {
					if (message.conversation.type === ConversationType.Group) {
						let groupInfo = wfc.getGroupInfo(message.conversation.target)
						let selfUserId = wfc.getUserId()
						if (groupInfo && groupInfo.owner === selfUserId) {
							return true
						}

						let groupMember = wfc.getGroupMember(message.conversation.target, selfUserId)
						if (groupMember && [GroupMemberType.Manager, GroupMemberType.Owner].indexOf(groupMember.type) > -1) {
							return true
						}
					}
					let delta = wfc.getServerDeltaTime()
					let now = new Date().getTime()
					if (message.direction === 0 && now - (numberValue(message.timestamp) - delta) < 60 * 1000) {
						return true
					}
				}
				return false
			},

			isLocalFile(message) {
				// TODO
				return false
			},

			isQuotable(message) {
				if (!message) {
					return false
				}
				return (
					[
						MessageContentType.VOIP_CONTENT_TYPE_START,
						MessageContentType.Voice,
						MessageContentType.Video,
						MessageContentType.Composite_Message,
						MessageContentType.CONFERENCE_CONTENT_TYPE_INVITE
					].indexOf(message.messageContent.type) <= -1
				)
			},

			copy(message) {
				let content = message.messageContent
				if (content instanceof TextMessageContent) {
					let selectedText = window.getSelection().toString()
					if (selectedText) {
						copyText(selectedText)
					} else {
						copyText(content.content)
					}
				} else {
					copyImg(content.remotePath)
				}
			},
			download(message) {
				// TODO
				// if (isElectron()) {
				//     downloadFile(message);
				// } else {
				//     if (!store.isDownloadingMessage(message.messageId)) {
				//         downloadFile(message)
				//         store.addDownloadingMessage(message.messageId)
				//     } else {
				//         // TODO toast 下载中
				//         console.log('file isDownloading')
				//     }
				// }
			},

			openFile(message) {
				let file = message.messageContent
				// TODO
				//shell.openItem(file.localPath);
			},

			openDir(message) {
				let file = message.messageContent
				// TODO
				// shell.showItemInFolder(file.localPath);
			},

			recallMessage(message) {
				wfc.recallMessage(message.messageUid, null, null)
			},

			forward(message) {
				this.$forward({
					forwardType: ForwardType.NORMAL,
					messages: [message]
				})
			},

			quoteMessage(message) {
				store.quoteMessage(message)
			},

			// call from child
			favMessages(messages) {
				console.log('fav messages')
				let compositeMessageContent = new CompositeMessageContent()
				let title = ''
				let msgConversation = messages[0].conversation
				if (msgConversation.type === ConversationType.Single) {
					let users = store.getUserInfos([wfc.getUserId(), msgConversation.target], '')
					title = users[0]._displayName + '和' + users[1]._displayName + '的聊天记录'
				} else {
					title = '群的聊天记录'
				}
				compositeMessageContent.title = title
				compositeMessageContent.messages = messages

				let message = new Message(msgConversation, compositeMessageContent)
				message.from = wfc.getUserId()
				this.favMessage(message)
			},

			favMessage(message) {
				// fixme 收藏
				// TODO 收藏
				uni.showToast({
					title: 'TODO ',
					icon: 'none'
				})
				return
				let favItem = FavItem.fromMessage(message)
				axios
					.post(
						'/fav/add',
						{
							messageUid: stringValue(favItem.messageUid),
							type: favItem.favType,
							convType: favItem.conversation.type,
							convTarget: favItem.conversation.target,
							convLine: favItem.conversation.line,
							origin: favItem.origin,
							sender: favItem.sender,
							title: favItem.title,
							url: favItem.url,
							thumbUrl: favItem.thumbUrl,
							data: favItem.data
						},
						{ withCredentials: true }
					)
					.then((response) => {
						if (response && response.data && response.data.code === 0) {
							this.$notify({
								// title: '收藏成功',
								text: '收藏成功',
								type: 'info'
							})
						} else {
							this.$notify({
								// title: '收藏成功',
								text: '收藏失败',
								type: 'error'
							})
						}
					})
					.catch((err) => {
						this.$notify({
							// title: '收藏失败',
							text: '收藏失败',
							type: 'error'
						})
					})
			},

			multiSelect(message) {
				this.toggleMessageMultiSelectionActionView(message)
			},

			playVoice(message) {
				if (amr) {
					amr.stop()
				}
				amr = new BenzAMRRecorder()
				let voice = message.messageContent
				amr.initWithUrl(voice.remotePath).then(() => {
					message._isPlaying = true
					amr.play()
				})
				amr.onEnded(() => {
					message._isPlaying = false
					store.playVoice(null)
				})
			},
			mentionMessageSenderTitle(message) {
				if (!message) {
					return ''
				}
				let displayName = wfc.getGroupMemberDisplayName(message.conversation.target, message.from)
				return '@' + displayName
			},

			mentionMessageSender(message) {
				this.$refs.messageInputView.mention(message.conversation.target, message.from)
			},

			onTouchStart(e) {
				this.isScroll = false
				this.touchStartX = e.touches[0].clientX
				this.touchStartY = e.touches[0].clientY
			},

			onTouchMove(e) {
				uni.hideKeyboard()

				let delX = e.touches[0].clientX - this.touchStartX
				let delY = e.touches[0].clientY - this.touchStartY
				if (Math.abs(delX) > 5 || Math.abs(delY) > 5) {
					this.isScroll = true
				}
			},

			showMessageContextMenu(e, message) {
				if (this.isScroll) {
					return
				}
				this.contextMenuX = e.touches[0].clientX
				this.contextMenuY = e.touches[0].clientY

				this.contextMenuItems = []
				if (this.isCopyable(message)) {
					this.contextMenuItems.push({
						title: '复制',
						message: message,
						tag: 'copy'
					})
				}
				if (this.isDownloadAble(message)) {
					this.contextMenuItems.push({
						title: '下载',
						message: message,
						tag: 'copy'
					})
				}
				this.contextMenuItems.push({
					title: '本地删除',
					message: message,
					tag: 'delete'
				})
				this.contextMenuItems.push({
					title: '远程删除',
					message: message,
					tag: 'deleteRemote'
				})
				if (this.isForwardable(message)) {
					this.contextMenuItems.push({
						title: '转发',
						message: message,
						tag: 'forward'
					})
				}
				if (this.isRecallable(message)) {
					this.contextMenuItems.push({
						title: '撤回',
						message: message,
						tag: 'recall'
					})
				}
				if (this.isQuotable(message)) {
					this.contextMenuItems.push({
						title: '引用',
						message: message,
						tag: 'quote'
					})
				}
				this.contextMenuItems.push({
					title: '多选',
					message: message,
					tag: 'multiSelection'
				})
				this.showContextMenu = true

				// <!--                    <li v-if="isCopyable(message)">-->
				//     <!--                        <a @click.prevent="copy(message)">{{ $t('common.copy') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isDownloadAble(message)">-->
				//     <!--                        <a @click.prevent="download(message)">{{ $t('common.save') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li>-->
				//     <!--                        <a @click.prevent="delMessage(message)">{{ $t('common.delete') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isForwardable(message)">-->
				//     <!--                        <a @click.prevent="_forward(message)">{{ $t('common.forward') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isFavable(message)">-->
				//     <!--                        <a @click.prevent="favMessage(message)">{{ $t('common.fav') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isQuotable(message)">-->
				//     <!--                        <a @click.prevent="quoteMessage(message)">{{ $t('common.quote') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li>-->
				//     <!--                        <a @click.prevent="multiSelect(message)">{{ $t('common.multi_select') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isRecallable(message)">-->
				//     <!--                        <a @click.prevent="recallMessage(message)">{{ $t('common.recall') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isLocalFile(message)">-->
				//     <!--                        <a @click.prevent="openFile(message)">{{ $t('common.open') }}</a>-->
				//     <!--                    </li>-->
				//     <!--                    <li v-if="isLocalFile(message)">-->
				//     <!--                        <a @click.prevent="openDir(message)">{{ $t('common.open_dir') }}</a>-->
				//     <!--                    </li>-->
			},

			onContextMenuItemSelect(t) {
				switch (t.tag) {
					case 'delete':
						console.log('wfc delete message', t.message.messageId)
						wfc.deleteMessage(t.message.messageId)
						break
					case 'deleteRemote':
						wfc.deleteRemoteMessageByUid(
							t.message.messageUid,
							() => {
								console.log('delete remote message success')
							},
							(err) => {
								console.log('delete remote message fail', err)
							}
						)
						break
					case 'forward':
						this.forward(t.message)
						break
					case 'recall':
						this.recallMessage(t.message)
						break
					case 'quote':
						store.quoteMessage(t.message)
						break
					case 'multiSelection':
						this.multiSelect(t.message)
						break
					default:
						uni.showToast({
							title: 'TODO ' + t.title,
							icon: 'none'
						})
						break
				}
				this.$emit('contextMenuClosed')
			},

			updateConversationTitle() {
				uni.setNavigationBarTitle({
					title: this.targetUserOnlineStateDesc
						? this.conversationTitle + `(${this.targetUserOnlineStateDesc})`
						: this.conversationTitle
				})
			},

			onPulling(e) {
				console.log('onpulling', e)
			},
			onRefresh() {
				console.log('onRresh...')
				if (this._freshing) {
					return
				}

				this._freshing = true
				this.triggered = true
				store.loadConversationHistoryMessages(
					() => {
						console.log('onRresh... 11')
						this.triggered = false
						this._freshing = false
					},
					() => {
						console.log('onRresh... 12')
						this.triggered = false
						this._freshing = false
					}
				)
			},
			onRestore() {
				this.triggered = 'restore' // 需要重置
				console.log('onRestore')
			},
			onAbort() {
				console.log('onAbort')
			}
		},

		mounted() {
			uni.setNavigationBarTitle({
				title: this.targetUserOnlineStateDesc
					? this.conversationTitle + `(${this.targetUserOnlineStateDesc})`
					: this.conversationTitle
			})
			this.$scrollToBottom()
			store.clearConversationUnreadStatus(this.conversationInfo.conversation)

			this.keyboardHeight = getItem('keyboardHeight')
			// #ifdef APP-PLUS
			uni.onKeyboardHeightChange((res) => {
				if (this.keyboardHeight !== res.height && res.height > 0) {
					this.keyboardHeight = res.height
					setItem('keyboardHeight', this.keyboardHeight)
				}
				if (this.$refs.messageInputView) {
					this.$refs.messageInputView.onKeyboardHeightChange(this.keyboardHeight, res.height)
				}
				this.scrollTop = 99919
				this.$nextTick(() => {
					this.scrollTop = 99999
				})
				// currentKeyboardHeight 显示扩展面板的时候，也应当置上
				console.log('------------- keyboardHeight', this.keyboardHeight, this.currentKeyboardHeight)
			})
			// #endif
			this.$on('openMessageContextMenu', (event, message) => {
				this.showMessageContextMenu(event, message)
			})
		},

		updated() {
			if (!this.sharedConversationState.currentConversationInfo) {
				return
			}
			console.log('conversationView updated', this.sharedConversationState.shouldAutoScrollToBottom)
			if (this.sharedConversationState.shouldAutoScrollToBottom) {
				// this.$scrollToBottom();
				this.scrollTop = 99998
			} else {
				// 用户滑动到上面之后，收到新消息，不自动滑动到最下面
			}
			if (this.sharedConversationState.currentConversationInfo) {
				let unreadCount = this.sharedConversationState.currentConversationInfo.unreadCount
				if (unreadCount.unread > 0) {
					store.clearConversationUnreadStatus(this.sharedConversationState.currentConversationInfo.conversation)
				}
			}

			this.conversationInfo = this.sharedConversationState.currentConversationInfo
		},

		computed: {
			conversationTitle() {
				let info = this.sharedConversationState.currentConversationInfo
				return info.conversation._target._displayName
			},
			targetUserOnlineStateDesc() {
				let info = this.sharedConversationState.currentConversationInfo
				return info.conversation._targetOnlineStateDesc
			},
			loadingIdentifier() {
				let conversation = this.sharedConversationState.currentConversationInfo.conversation
				return conversation.type + '-' + conversation.target + '-' + conversation.line
			},
			currentVoiceMessage() {
				let voice = this.sharedConversationState.currentVoiceMessage
				if (voice) {
					this.playVoice(voice)
				} else {
					if (amr) {
						amr.stop()
					}
				}
				return null
			},

			lastMessageId() {
				return this.conversationInfo.lastMessage ? this.conversationInfo.lastMessage.messageId : ''
			}
		},

		directives: {
			// ClickOutside
		}
	}
</script>

<style lang="less" scoped>
	.conversation-empty-container {
		height: 100%;
		width: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		/*border-left: 1px solid #e6e6e6;*/
	}

	.conversation-content-container {
		position: relative;
		display: flex;
		height: 100vh;
		overflow: hidden;
		flex-direction: column;
		background-color: #f3f3f3;
		/*padding: 0 12px;*/
	}

	.viewider-handler::before {
		cursor: row-resize;
		content: '';
		display: block;
		width: 100%;
		height: 3px;
		border-top: 1px solid #e2e2e2;
		margin: 0 auto;
	}

	.message-list-container {
		min-height: 100px;
		flex: 1 1 auto;
		overflow: hidden;
	}

	.message-list {
		height: 100%;
		overflow: auto;
	}
</style>
